<template>
  <div class="page">
    <div class="page-header">
      <a-row :align="'middle'">
        <img :src="docsData.downloadImageUrl" class="algo-img" draggable="false" />
        <div class="algo-name">{{ docsData.algorithmServiceName }}</div>
      </a-row>
      <a-row class="tab-list">
        <a-col
          v-for="tab in tabList"
          :key="tab.val"
          class="tab cursor"
          :class="{ active: activeTab === tab.val }"
          @click="changTab(tab.val)"
        >
          {{ tab.name }}
        </a-col>
      </a-row>
    </div>

    <div class="page-main">
      <div class="version-list">
        <template v-if="activeTab === 'algorithmApiDocumentVOS'">
          <div
            v-for="item in currentVersionList"
            :key="item.id"
            class="version-item cursor"
            :class="{ active: item.operateMethodDocumentVOS[0].id === currentVersionId }"
            @click="currentVersionId = item.operateMethodDocumentVOS[0].id"
          >
            <i class="ri-file-line icon"></i> v{{ item.versionName }}
          </div>
        </template>
        <template v-else-if="activeTab === 'algorithmSdkDocumentVOS'">
          <div v-for="item in currentVersionList" :key="item.id" class="sdk-version">
            <div class="version-title">v{{ item.versionName }}</div>
            <div
              v-for="childItem in item.operateMethodDocumentVOS"
              :key="`${item.versionName}_${childItem.documentName}`"
              class="version-item cursor"
              :class="{ active: childItem.id == currentVersionId }"
              @click="currentVersionId = childItem.id"
            >
              <i class="ri-file-line icon"></i> {{ childItem?.platformName + '_' + childItem?.languageName }}
            </div>
          </div>
        </template>
      </div>

      <a-spin class="my-a-spin" :spinning="isSpin" tip="加载中" wrapper-class-name="docs-content">
        <a-button class="download-btn" @click="download">
          <i class="ri-file-download-line icon"></i>
          下载
        </a-button>
        <iframe v-if="pdfUrl" class="iframe1" :src="'/pdfjs/web/viewer.html?file=' + pdfUrl" frameborder="0" width="100%" height="99%">
        </iframe>
      </a-spin>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, watch } from 'vue'
  import { useRoute, useRouter } from 'vue-router'

  import { algoServiceApi, fetchDownload, getFileUrl } from '@/services/api'
  import { waitLoading } from '@/utils'

  export interface DocsData {
    algorithmApiDocumentVOS: Version[]
    algorithmSdkDocumentVOS: Version[]
    algorithmServiceName: string
    downloadImageUrl: string
  }

  export interface Version {
    id: string
    versionId: string
    versionName: string
    documentUrl: string
    operateMethodDocumentVOS: {
      id: string
      documentName: string
      documentUrl: string
      platformName: string
      languageName: string
    }[]
  }

  export type ActiveTab = 'algorithmApiDocumentVOS' | 'algorithmSdkDocumentVOS'

  interface Tab {
    name: string
    val: ActiveTab
  }

  const route = useRoute()
  const router = useRouter()

  const docsData = ref<DocsData>({
    algorithmServiceName: '',
    downloadImageUrl: '',
    algorithmApiDocumentVOS: [],
    algorithmSdkDocumentVOS: []
  })
  const tabList = ref<Tab[]>([])
  const activeTab = ref<ActiveTab>((route.query.type as ActiveTab) || 'algorithmApiDocumentVOS')
  const currentVersionList /* 当前版本列表 */ = ref<Version[]>([])
  const currentVersionId /* 当前文档id */ = ref<string>()
  const pdfUrl = ref('')
  const isSpin = ref(false)

  // 监听数据及tab变化，给文档列表及选中文档赋值
  watch([docsData, activeTab], async ([newDocsData, newActiveTab]) => {
    currentVersionList.value = newDocsData[newActiveTab]
    if (!currentVersionList.value.length) {
      return
    }
    if (newActiveTab === 'algorithmApiDocumentVOS') {
      currentVersionId.value = currentVersionList.value[0].operateMethodDocumentVOS[0].id
    } else if (newActiveTab === 'algorithmSdkDocumentVOS') {
      currentVersionId.value = currentVersionList.value[0].operateMethodDocumentVOS[0].id
    }
  })

  // 监听选中文档的id，动态获取在线的pdf地址
  watch(
    currentVersionId,
    async v => {
      if (!v) {
        return
      }

      let url =
        currentVersionList.value.flatMap(it => it.operateMethodDocumentVOS).find(it => it.id === currentVersionId.value)?.documentUrl || ''
      if (!url) {
        return
      }
      // 因后端问题路径和windows有差异，需对文件名进行处理
      url = url.replace(/\\/g, '/')
      isSpin.value = true
      try {
        const res = await getFileUrl(url)
        pdfUrl.value = decodeURI(res.data)
      } catch (error) {
        console.log(error)
      }
      // 延迟一秒再显示，因为涉及到iframe加载
      setTimeout(() => {
        isSpin.value = false
      }, 1000)
    },
    { immediate: true }
  )

  const getDocsData = async () => {
    const res = await algoServiceApi.docs({ id: route.params.id })
    docsData.value = res.data

    // 根据数据给tab赋值
    let _tabList = []
    if (docsData.value.algorithmApiDocumentVOS?.length) {
      _tabList.push({
        name: 'API使用文档',
        val: 'algorithmApiDocumentVOS'
      } as Tab)
    }
    if (docsData.value.algorithmSdkDocumentVOS?.length) {
      _tabList.push({
        name: 'SDK使用文档',
        val: 'algorithmSdkDocumentVOS'
      } as Tab)
    }
    tabList.value = [..._tabList]
  }

  const changTab = (val: ActiveTab) => {
    activeTab.value = val
    // 同步切换路由参数
    router.replace({
      query: {
        type: val
      }
    })
  }

  const download = async () => {
    let currentItem =
      currentVersionList.value.flatMap(it => it.operateMethodDocumentVOS).find(it => it.id === currentVersionId.value) || null
    if (!currentItem) {
      return
    }

    await waitLoading(fetchDownload(pdfUrl.value, currentItem.documentName), {
      loadingText: '数据准备中,请耐心等待...',
      errorText: '文件下载失败',
      successText: '文件下载成功'
    })
  }

  getDocsData()
</script>

<style lang="less" scoped>
  @import '@/styles/mixins.less';

  .page {
    .page-header {
      position: relative;
      padding: 48px 40px 0;
      height: 160px;
      border-bottom: 1px solid #d9d9db;
      background: #fafafa;

      .algo-img {
        width: 40px;
        height: 40px;
      }

      .algo-name {
        margin-left: 8px;
        font-weight: 700;
        font-size: 24px;
        line-height: 34px;
        color: rgba(16, 16, 20, 0.95);
      }

      .tab-list {
        position: absolute;
        bottom: 0;
        left: 40px;
        height: 32px;
        .fw500();

        font-size: 16px;
        line-height: 24px;
        color: rgba(25, 25, 48, 0.45);

        .tab {
          &.active {
            color: rgba(16, 16, 20, 0.95);
            border-bottom: 3px solid rgba(24, 104, 233, 1);
          }

          & + .tab {
            margin-left: 40px;
          }
        }
      }
    }

    .page-main {
      display: flex;
      overflow: hidden;
      height: calc(100vh - 160px - 54px);
    }

    .version-list {
      overflow: hidden auto;
      padding-top: 24px;
      width: 320px;
      border-right: 1px solid #d9d9db;

      .sdk-version {
        margin-bottom: 40px;

        .version-title {
          display: flex;
          align-items: center;
          padding-left: 24px;
          height: 46px;
          font-size: 14px;
          color: rgba(25, 25, 48, 0.45);
          font-weight: 700;
          line-height: 22px;
        }
      }

      .version-item {
        display: flex;
        align-items: center;
        padding-left: 43px;
        width: 320px;
        height: 64px;
        font-weight: 400;
        font-size: 16px;
        line-height: 24px;
        color: rgba(16, 16, 20, 0.95);

        .icon {
          margin-right: 8px;
          font-size: 24px;
          color: #1868e9;
        }

        &.active {
          background: rgba(30, 49, 143, 0.12);
          border-right: 3px solid #649af0;
        }
      }
    }

    .docs-content {
      position: relative;
      overflow-y: auto;
      flex: 1;

      .download-btn {
        position: absolute;
        top: 40px;
        right: 24px;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 82px;
        height: 38px;
        background: #fff;
        border: 1px solid #d9d9db;
        border-radius: 4px;
        cursor: pointer;

        .icon {
          margin-right: 8px;
        }
      }

      .my-a-spin {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100%;
        flex: 1;
        flex-direction: column;
      }

      :deep(.ant-spin-container) {
        height: 100%;
      }
    }
  }
</style>
